/*  * To change this template, choose Tools | Templates  * and open the template in the editor.  */
package com.prabhu.jeazyprops.props;

import com.prabhu.cmdwindow.ui.Display;
import com.prabhu.jeazyprops.bean.KeyValue;
import com.prabhu.jeazyprops.interfaces.PropsEncrypt;
import com.prabhu.jeazyprops.validation.Validator;
import java.awt.Button;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.LayoutManager;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Properties;
import java.util.jar.JarFile;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JCheckBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.border.EtchedBorder;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

/**
 * * This is the Base Class for the Property Bean Class
 *
 *  * @author Pinky
 */
public abstract class BaseProps extends Display {

    private Properties lProperties;
    private File lPropsFile;
    private PropsEncrypt lPropsEncrypt;
    protected String lPropsFilePath;
    protected String lSufixProps = "";
    protected String lPrefixProps = "";
    //private boolean isAbleToSave = false;
    private PropsFiletype lPropsFiletype;
    private PropsFilelocation lPropsFilelocation;

    public enum PropsFiletype {

        XML, PROPERTIES
    };

    public enum PropsFilelocation {

        EXTERNAL, INTERNAL
    };

    /**
     * Sets the Encryption algorithm for the properties
     *
     * @param pPropsEncrypt
     */
    public void setEncryption(PropsEncrypt pPropsEncrypt) {
        lPropsEncrypt = pPropsEncrypt;
    }

    /**
     * Loads the Properties from File to Bean
     *
     * @param PropsFilePath Relative or Absolute path of the Properties File
     */
    public void loadProperties(String PropsFilePath) {
        lPropsFilePath = PropsFilePath;

        if (lPropsFilePath.endsWith(".xml")) {
            lPropsFiletype = PropsFiletype.XML;
        } else if (lPropsFilePath.endsWith(".properties")) {
            lPropsFiletype = PropsFiletype.PROPERTIES;
        }
        InputStream pFileInputStream = null;
        lPropsFile = new File(PropsFilePath);

        try {
            if (lPropsFile.exists()) {
                pFileInputStream = new FileInputStream(lPropsFile);
                lPropsFilelocation = PropsFilelocation.EXTERNAL;
            } else {
                StackTraceElement[] s = new Exception().fillInStackTrace().getStackTrace();
                String callingClass = s[s.length - 2].getClassName();
                System.out.println("Class Name = " + callingClass);
                pFileInputStream = ClassLoader.getSystemClassLoader().loadClass(callingClass).getResourceAsStream("/" + lPropsFilePath);
                //Class.forName(callingClass).getClass().getResourceAsStream("/" + lPropsFilePath);
                lPropsFilelocation = PropsFilelocation.INTERNAL;
            }
            if (pFileInputStream == null) {
                if (lPropsFiletype == PropsFiletype.XML) {
                    createNewXMLFile();
                } else if (lPropsFiletype == PropsFiletype.PROPERTIES) {
                    lPropsFile.createNewFile();
                }
                pFileInputStream = new FileInputStream(lPropsFile);
                lPropsFilelocation = PropsFilelocation.EXTERNAL;
            }
            //isAbleToSave = true;
            loadProperties(pFileInputStream, lPropsFiletype);
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(BaseProps.class.getName()).log(Level.SEVERE, null, ex);
        } catch (FileNotFoundException ex) {
            JOptionPane.showMessageDialog(null, "Properties File Not Found", "Alert", JOptionPane.ERROR_MESSAGE);
        } catch (IOException ex) {
            JOptionPane.showMessageDialog(null, "Cannot able to Create Properties File", "Alert", JOptionPane.ERROR_MESSAGE);
        } finally {
            try {
                if (pFileInputStream != null) {
                    pFileInputStream.close();
                }
            } catch (IOException ex) {
                JOptionPane.showMessageDialog(null, "Cannot able to Close Properties File", "Alert", JOptionPane.ERROR_MESSAGE);
            }
        }
    }

    /**
     * Loads the Properties from input stream to Bean
     *
     * @param pFileInputStream input stream of a file stream
     */
    private void loadProperties(InputStream pFileInputStream, PropsFiletype pPropsFiletype) {
        //isAbleToSave = true;
        lPropsFiletype = pPropsFiletype;
        lProperties = new Properties();
        try {
            if (lPropsFiletype == PropsFiletype.XML) {
                lProperties.loadFromXML(pFileInputStream);
            } else if (lPropsFiletype == PropsFiletype.PROPERTIES) {
                lProperties.load(pFileInputStream);
            }
            readProperties();
        } catch (IOException ex) {
            JOptionPane.showMessageDialog(null, "Cannot able to Read Properties File (Format Error)", "Alert", JOptionPane.ERROR_MESSAGE);
        } finally {
            try {
                if (pFileInputStream != null) {
                    pFileInputStream.close();
                }
            } catch (IOException ex) {
                JOptionPane.showMessageDialog(null, "Cannot able to Close Properties File", "Alert", JOptionPane.ERROR_MESSAGE);
            }
        }
    }

    /**
     * * Gets the integer property
     *
     *      * @param Key Property Name (key value)
     * @param isEncrypt Whether the value is encrypted
     * @return The integer Property
     */
    private int getIntegerProperty(String Key, boolean isEncrypt) {
        try {
            if (isEncrypt) {
                if (lProperties.getProperty(Key, "0").equals("0")) {
                    return Integer.valueOf(lProperties.getProperty(Key, "0"));
                } else {
                    if (lPropsEncrypt == null) {
                        JOptionPane.showMessageDialog(null, "No Encryption Initalised", "Alert", JOptionPane.WARNING_MESSAGE);
                    }
                    return Integer.valueOf(lPropsEncrypt.decrypt(lProperties.getProperty(Key)));
                }
            } else {
                return Integer.valueOf(lProperties.getProperty(Key, "0"));
            }
        } catch (NumberFormatException ex) {
            return 0;
        }
    }

    /**
     * * Gets the double property
     *
     *      * @param Key Property Name (key value)
     * @param isEncrypt Whether the value is encrypted
     * @return The double Property
     */
    private double getDoubleProperty(String Key, boolean isEncrypt) {
        try {
            if (isEncrypt) {
                if (lProperties.getProperty(Key, "0.0").equals("0.0")) {
                    return Double.valueOf(lProperties.getProperty(Key, "0.0"));
                } else {
                    if (lPropsEncrypt == null) {
                        JOptionPane.showMessageDialog(null, "No Encryption Initalised", "Alert", JOptionPane.WARNING_MESSAGE);
                    }
                    return Double.valueOf(lPropsEncrypt.decrypt(lProperties.getProperty(Key)));
                }
            } else {
                return Double.valueOf(lProperties.getProperty(Key, "0.0"));
            }
        } catch (NumberFormatException ex) {
            return 0.0;
        }
    }

    /**
     * * Gets the float property
     *
     *      * @param Key Property Name (key value)
     * @param isEncrypt Whether the value is encrypted
     * @return The double Property
     */
    private float getFloatProperty(String Key, boolean isEncrypt) {
        try {
            if (isEncrypt) {
                if (lProperties.getProperty(Key, "0.0").equals("0.0")) {
                    return Float.valueOf(lProperties.getProperty(Key, "0.0"));
                } else {
                    if (lPropsEncrypt == null) {
                        JOptionPane.showMessageDialog(null, "No Encryption Initalised", "Alert", JOptionPane.WARNING_MESSAGE);
                    }
                    return Float.valueOf(lPropsEncrypt.decrypt(lProperties.getProperty(Key)));
                }
            } else {
                return Float.valueOf(lProperties.getProperty(Key, "0.0"));
            }
        } catch (NumberFormatException ex) {
            return 0;
        }
    }

    /**
     * * Gets the String property
     *
     *      * @param Key Property Name (key value)
     * @param isEncrypt Whether the value is encrypted
     * @return The String Property
     */
    private String getStringProperty(String Key, boolean isEncrypt) {
        if (isEncrypt) {
            if (lProperties.getProperty(Key, "").equals("")) {
                return lProperties.getProperty(Key, "");
            } else {
                if (lPropsEncrypt == null) {
                    JOptionPane.showMessageDialog(null, "No Encryption Initalised", "Alert", JOptionPane.WARNING_MESSAGE);
                }
                return lPropsEncrypt.decrypt(lProperties.getProperty(Key));
            }
        } else {
            return lProperties.getProperty(Key, "");
        }
    }

    /**
     * * Gets the Boolean property
     *
     *      * @param Key Property Name (key value)
     * @param isEncrypt Whether the value is encrypted
     * @return The Boolean Property
     */
    private boolean getBooleanProperty(String Key, boolean isEncrypt) {
        try {
            if (isEncrypt) {
                if (lPropsEncrypt == null) {
                    JOptionPane.showMessageDialog(null, "No Encryption Initalised", "Alert", JOptionPane.WARNING_MESSAGE);
                }
                return Boolean.valueOf(lPropsEncrypt.decrypt(lProperties.getProperty(Key)));
            } else {
                return Boolean.valueOf(lProperties.getProperty(Key, "false"));
            }
        } catch (NumberFormatException ex) {
            return false;
        }
    }

    /**
     * * Sets the integer property
     *
     *      * @param Key Property Name (key value)
     * @param Value Property Value (key value)
     * @return The integer Property
     */
    private void putStringProperty(String Key, String Value) {
        putStringProperty(Key, Value, false);
    }

    /**
     * * Sets the String property
     *
     *      * @param Key Property Name (key value)
     * @param Value Property Value (key value)
     * @param isEncrypt Whether the value is encrypted
     * @return The integer Property
     */
    private void putStringProperty(String Key, String Value, boolean isEncrypt) {
        if (isEncrypt) {
            lProperties.put(Key, lPropsEncrypt.encrypt(Value));
        } else {
            lProperties.put(Key, Value);
        }
    }

    /**
     * * Updates or saves the properties to the file
     *
     *      * @return
     */
    private boolean updateProperties() {
        String pClassName = this.getClass().getName();
        try {
            Class<?> forName = Class.forName(pClassName);
            Object cast = forName.cast(this);
            Method[] methods = forName.getMethods();
            for (int i = 0; i < methods.length; i++) {
                Method method = methods[i];
                if (method.getDeclaringClass().getName().equals(pClassName) && method.getName().startsWith("get")) {
                    String invoke = String.valueOf(method.invoke(cast));
                    Field field = null;
                    try {
                        field = forName.getField(lPrefixProps + method.getName().substring(3) + lSufixProps);
                    } catch (NoSuchFieldException ex) {
                        continue;
                    }
                    if (field == null) {
                        continue;
                    }
                    KeyValue currentValue = (KeyValue) field.get(cast);
                    putStringProperty(currentValue.key, invoke, currentValue.isEncrypted);
                }
            }

            if (lPropsFilelocation == PropsFilelocation.EXTERNAL) {
                if (lPropsFiletype == PropsFiletype.XML) {
                    lProperties.storeToXML(new FileOutputStream(lPropsFilePath), null);
                } else if (lPropsFiletype == PropsFiletype.PROPERTIES) {
                    lProperties.store(new FileOutputStream(lPropsFilePath), null);
                }
            } else if (lPropsFilelocation == PropsFilelocation.INTERNAL) {
                if (lPropsFiletype == PropsFiletype.XML) {
                    new File(lPropsFilePath.substring(0, lPropsFilePath.lastIndexOf("/"))).mkdirs();
                    createNewXMLFile();
                    FileOutputStream fileOutputStream = new FileOutputStream(lPropsFilePath);
                    lProperties.storeToXML(fileOutputStream, null);
                    fileOutputStream.close();
                } else if (lPropsFiletype == PropsFiletype.PROPERTIES) {
                    new File(lPropsFilePath.substring(0, lPropsFilePath.lastIndexOf("/"))).mkdirs();
                    new File(lPropsFilePath).createNewFile();
                    FileOutputStream fileOutputStream = new FileOutputStream(lPropsFilePath);
                    lProperties.store(fileOutputStream, null);
                    fileOutputStream.close();
                }
            }
            return true;
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return false;
    }

    /**
     * * Prints the Properties
     */
    public void printProperties() {
        String pClassName = this.getClass().getName();
        try {
            Class<?> forName = Class.forName(pClassName);
            Object cast = forName.cast(this);
            Method[] methods = forName.getMethods();
            printHeader();
            printColumn("Properties List");
            printHeader();
            for (int i = 0; i < methods.length; i++) {
                Method method = methods[i];
                if (method.getDeclaringClass().getName().equals(pClassName) && method.getName().startsWith("get")) {
                    Field field = null;
                    try {
                        field = forName.getField(lPrefixProps + method.getName().substring(3) + lSufixProps);
                    } catch (NoSuchFieldException ex) {
                        continue;
                    }
                    if (field == null) {
                        continue;
                    }
                    String invoke = String.valueOf(method.invoke(cast));
                    printColumn(method.getName().substring(3), invoke);
                }
            }
            printHeader();
            printColumn("Powered By Prabhu.P (p.r.c.prabhu@gmail.com)");
            printHeader();
        } catch (Exception ex) {
        }
    }

    /**
     * * Displays the Properties in a GUI for Editing and Updating
     */
    public void DisplaySettings() {
        JDialog lJDialog = null;
        lJDialog = new JDialog(lJDialog, "Properties Configuration") {
            @Override
            public void setLayout(LayoutManager manager) {
                super.setLayout(manager);
                try {
                    for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                        if ("Windows".equals(info.getName())) {
                            javax.swing.UIManager.setLookAndFeel(info.getClassName());
                            break;
                        }
                    }
                } catch (ClassNotFoundException ex) {
                } catch (InstantiationException ex) {
                } catch (IllegalAccessException ex) {
                } catch (javax.swing.UnsupportedLookAndFeelException ex) {
                }
            }
        };
        lJDialog.setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        Validator lValidator = new Validator(this);
        JPanel lPanel = new JPanel();
        String pClassName = this.getClass().getName();
        int compscount = 0;
        try {
            Class<?> forName = Class.forName(pClassName);
            Object cast = forName.cast(this);
            Method[] methods = forName.getMethods();
            lPanel.setLayout(new GridBagLayout());
            GridBagConstraints lBagConstraints = new GridBagConstraints();
            lBagConstraints.fill = GridBagConstraints.HORIZONTAL;
            lBagConstraints.weightx = 1.0;
            for (int i = 0; i < methods.length; i++) {
                Method method = methods[i];
                if (method.getDeclaringClass().getName().equals(pClassName) && method.getName().startsWith("get")) {
                    String invoke = String.valueOf(method.invoke(cast));
                    Field field = null;
                    try {
                        field = forName.getField(lPrefixProps + method.getName().substring(3) + lSufixProps);
                    } catch (NoSuchFieldException ex) {
                        continue;
                    }
                    if (field == null) {
                        continue;
                    }
                    KeyValue currentKey = (KeyValue) field.get(cast);
                    lBagConstraints.fill = GridBagConstraints.CENTER;
                    lBagConstraints.gridx = 0;
                    lBagConstraints.gridy = compscount;
                    lBagConstraints.insets = new Insets(5, 10, 5, 5);
                    lBagConstraints.anchor = GridBagConstraints.EAST;
                    lBagConstraints.weightx = 0;
                    if (currentKey.displayName != null) {
                        lPanel.add(new JLabel(currentKey.displayName + " : "), lBagConstraints);
                        lBagConstraints.fill = GridBagConstraints.HORIZONTAL;
                        lBagConstraints.gridx = 1;
                        lBagConstraints.gridy = compscount;
                        lBagConstraints.insets = new Insets(5, 5, 5, 10);
                        lBagConstraints.weightx = 1.0;
                        if (method.getReturnType().getName().equals("java.lang.String") || method.getReturnType().getName().equals("int") || method.getReturnType().getName().equals("java.lang.Integer") || method.getReturnType().getName().equals("double") || method.getReturnType().getName().equals("java.lang.Double") || method.getReturnType().getName().equals("float") || method.getReturnType().getName().equals("java.lang.Float")) {
                            if (currentKey.isEncrypted) {
                                currentKey.lComponent = new JPasswordField(invoke);
                                currentKey.lComponent.getAccessibleContext().setAccessibleName(lPrefixProps + method.getName().substring(3) + lSufixProps);
                                currentKey.lComponent.setInputVerifier(lValidator);
                            } else {
                                currentKey.lComponent = new JTextField(invoke);
                                currentKey.lComponent.getAccessibleContext().setAccessibleName(lPrefixProps + method.getName().substring(3) + lSufixProps);
                                currentKey.lComponent.setInputVerifier(lValidator);
                            }
                        } else if (method.getReturnType().getName().equals("java.lang.Boolean") || method.getReturnType().getName().equals("boolean")) {
                            currentKey.lComponent = new JCheckBox();
                            currentKey.lComponent.getAccessibleContext().setAccessibleName(lPrefixProps + method.getName().substring(3) + lSufixProps);
                            ((JCheckBox) currentKey.lComponent).setSelected(Boolean.valueOf(invoke));
                        }
                        lPanel.add(currentKey.lComponent, lBagConstraints);
                        compscount++;
                    }
                }
            }
//            if (isAbleToSave) {
            lBagConstraints.gridx = 0;
            lBagConstraints.gridwidth = 2;
            lBagConstraints.gridy = compscount;
            Button button = new Button("Save");
            button.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (ValidateData()) {// && isAbleToSave) {
                        packData();
                        if (updateProperties()) {
                            JOptionPane.showMessageDialog(null, "Property file " + lPropsFilePath + " Updated Successfully", "Update Success", JOptionPane.INFORMATION_MESSAGE);
                        } else {
                            JOptionPane.showMessageDialog(null, "Property file " + lPropsFilePath + " Update Failed", "Error", JOptionPane.ERROR_MESSAGE);
                        }
                    } else {
                        JOptionPane.showMessageDialog(null, "Not able to update, Validation error.", "Alert", JOptionPane.WARNING_MESSAGE);
                    }
                }
            });
            lPanel.add(button, lBagConstraints);
            compscount++;
//            }
            EtchedBorder etchedBorder = new EtchedBorder(EtchedBorder.LOWERED);
            etchedBorder.getBorderInsets(lPanel);
            lPanel.setBorder(etchedBorder);
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = gbc.gridy = 0;
            gbc.gridwidth = gbc.gridheight = 1;
            gbc.fill = GridBagConstraints.BOTH;
            gbc.anchor = GridBagConstraints.NORTHWEST;
            gbc.weightx = gbc.weighty = 100;
            gbc.insets = new Insets(10, 10, 10, 10);
            lJDialog.setLayout(new GridBagLayout());
            lJDialog.add(lPanel, gbc);
            lJDialog.setBounds(new Rectangle((520), (compscount * 35) + 40));
            setWindowParameters(lJDialog);
            lJDialog.setVisible(true);
            lJDialog.setResizable(false);
        } catch (Exception ex) {
        }
    }

    /**
     * * Validates the text fields
     *
     *      * @return true if all validation matches
     */
    private boolean ValidateData() {
        String pClassName = this.getClass().getName();
        boolean lReturn = true;
        try {
            Class<?> forName = Class.forName(pClassName);
            Object cast = forName.cast(this);
            Method[] methods = forName.getMethods();
            for (int i = 0; i < methods.length; i++) {
                Method method = methods[i];
                if (method.getDeclaringClass().getName().equals(pClassName) && method.getName().startsWith("set")) {
                    Field field = null;
                    try {
                        field = forName.getField(lPrefixProps + method.getName().substring(3) + lSufixProps);
                    } catch (NoSuchFieldException ex) {
                        continue;
                    }
                    if (field == null) {
                        continue;
                    }
                    KeyValue currentKey = (KeyValue) field.get(cast);
                    if (currentKey.displayName != null) {
                        Class<?>[] parameterTypes = method.getParameterTypes();
                        if (parameterTypes[0].getName().equals("java.lang.String") || parameterTypes[0].getName().equals("int") || parameterTypes[0].getName().equals("java.lang.Integer") || parameterTypes[0].getName().equals("double") || parameterTypes[0].getName().equals("java.lang.Double") || parameterTypes[0].getName().equals("float") || parameterTypes[0].getName().equals("java.lang.Float")) {
                            if (currentKey.isEncrypted) {
                                lReturn = lReturn && ((JPasswordField) currentKey.lComponent).getInputVerifier().verify(currentKey.lComponent);
                            } else {
                                lReturn = lReturn && ((JTextField) currentKey.lComponent).getInputVerifier().verify(currentKey.lComponent);
                            }
                        }
                    }
                }
            }
        } catch (Exception ex) {
            lReturn = false;
        }
        return lReturn;
    }

    /**
     * * Packs the Data from Bean fro Updating
     */
    private void packData() {
        String pClassName = this.getClass().getName();
        try {
            Class<?> forName = Class.forName(pClassName);
            Object cast = forName.cast(this);
            Method[] methods = forName.getMethods();
            for (int i = 0; i < methods.length; i++) {
                Method method = methods[i];
                if (method.getDeclaringClass().getName().equals(pClassName) && method.getName().startsWith("set")) {
                    Field field = null;
                    try {
                        field = forName.getField(lPrefixProps + method.getName().substring(3) + lSufixProps);
                    } catch (NoSuchFieldException ex) {
                        continue;
                    }
                    if (field == null) {
                        continue;
                    }
                    KeyValue currentKey = (KeyValue) field.get(cast);
                    if (currentKey.displayName != null) {
                        Class<?>[] parameterTypes = method.getParameterTypes();
                        if (parameterTypes[0].getName().equals("java.lang.String")) {
                            if (currentKey.isEncrypted) {
                                String Property = String.valueOf(((JPasswordField) currentKey.lComponent).getPassword());
                                method.invoke(cast, Property);
                            } else {
                                String Property = ((JTextField) currentKey.lComponent).getText();
                                method.invoke(cast, Property);
                            }
                        } else if (parameterTypes[0].getName().equals("int") || parameterTypes[0].getName().equals("java.lang.Integer")) {
                            if (currentKey.isEncrypted) {
                                Integer Property = Integer.valueOf(String.valueOf(((JPasswordField) currentKey.lComponent).getPassword()));
                                method.invoke(cast, Property);
                            } else {
                                Integer Property = Integer.valueOf(((JTextField) currentKey.lComponent).getText());
                                method.invoke(cast, Property);
                            }
                        } else if (parameterTypes[0].getName().equals("double") || parameterTypes[0].getName().equals("java.lang.Double")) {
                            if (currentKey.isEncrypted) {
                                Integer Property = Integer.valueOf(String.valueOf(((JPasswordField) currentKey.lComponent).getPassword()));
                                method.invoke(cast, Property);
                            } else {
                                Double Property = Double.valueOf(((JTextField) currentKey.lComponent).getText());
                                method.invoke(cast, Property);
                            }
                        } else if (parameterTypes[0].getName().equals("float") || parameterTypes[0].getName().equals("java.lang.Float")) {
                            if (currentKey.isEncrypted) {
                                Float Property = Float.valueOf(String.valueOf(((JPasswordField) currentKey.lComponent).getPassword()));
                                method.invoke(cast, Property);
                            } else {
                                Integer Property = Integer.valueOf(((JTextField) currentKey.lComponent).getText());
                                method.invoke(cast, Property);
                            }
                        } else if (parameterTypes[0].getName().equals("boolean") || parameterTypes[0].getName().equals("java.lang.Boolean")) {
                            Boolean Property = Boolean.valueOf(((JCheckBox) currentKey.lComponent).isSelected());
                            method.invoke(cast, Property);
                        }
                    }
                }
            }
        } catch (Exception ex) {
        }
    }

    /**
     * * Sets the window Position
     *
     *      * @param aThis The Widow container
     */
    private void setWindowParameters(Container aThis) {
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        int x = (screenSize.width - aThis.getWidth()) / 2;
        int y = (screenSize.height - aThis.getHeight()) / 2;
        aThis.setBounds(x, y, aThis.getWidth(), aThis.getHeight());
    }

    /**
     * * Reads from properties to Bean
     *
     *      * @return
     */
    private boolean readProperties() {
        String pClassName = this.getClass().getName();
        try {
            Class<?> forName = Class.forName(pClassName);
            Object cast = forName.cast(this);
            Method[] methods = forName.getMethods();
            for (int i = 0; i < methods.length; i++) {
                Method method = methods[i];
                if (method.getDeclaringClass().getName().equals(pClassName) && method.getName().startsWith("set")) {
                    Field field = null;
                    try {
                        field = forName.getField(lPrefixProps + method.getName().substring(3) + lSufixProps);
                    } catch (NoSuchFieldException ex) {
                        continue;
                    }
                    if (field == null) {
                        continue;
                    }
                    KeyValue CurrentField = (KeyValue) field.get(cast);
                    Class<?>[] parameterTypes = method.getParameterTypes();
                    if (parameterTypes[0].getName().equals("java.lang.String")) {
                        String stringProperty = getStringProperty(CurrentField.key, CurrentField.isEncrypted);
                        method.invoke(cast, stringProperty);
                    } else if (parameterTypes[0].getName().equals("int") || parameterTypes[0].getName().equals("java.lang.Integer")) {
                        Integer cast1 = getIntegerProperty(CurrentField.key, CurrentField.isEncrypted);
                        method.invoke(cast, cast1);
                    } else if (parameterTypes[0].getName().equals("double") || parameterTypes[0].getName().equals("java.lang.Double")) {
                        Double cast1 = getDoubleProperty(CurrentField.key, CurrentField.isEncrypted);
                        method.invoke(cast, cast1);
                    } else if (parameterTypes[0].getName().equals("float") || parameterTypes[0].getName().equals("java.lang.Float")) {
                        Float cast1 = getFloatProperty(CurrentField.key, CurrentField.isEncrypted);
                        method.invoke(cast, cast1);
                    } else if (parameterTypes[0].getName().equals("boolean") || parameterTypes[0].getName().equals("java.lang.Boolean")) {
                        Boolean cast1 = getBooleanProperty(CurrentField.key, CurrentField.isEncrypted);
                        method.invoke(cast, cast1);
                    }
                }
            }
            return true;
        } catch (Exception ex) {
        }
        return false;
    }

    /**
     * * Creates a Empty XML Properties File
     */
    private void createNewXMLFile() {
        try {
            DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
            Document doc = docBuilder.newDocument();
            Element rootElement = doc.createElement("properties");
            doc.appendChild(rootElement);
            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            Transformer transformer = transformerFactory.newTransformer();
            transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, "http://java.sun.com/dtd/properties.dtd");
            DOMSource source = new DOMSource(doc);
            StreamResult result = new StreamResult(new File(lPropsFilePath));
            transformer.transform(source, result);
        } catch (TransformerException ex) {
        } catch (ParserConfigurationException ex) {
        }
    }

    /**
     * * Returns the Data type of the field
     *
     *      * @param lField name to find the Data type
     * @return Data type name as String
     */
    public String getDatatype(String lField) {
        String pClassName = this.getClass().getName();
        String lReturn = "";
        try {
            Class<?> forName = Class.forName(pClassName);
            String fieldName = forName.getField(lField).getName();
            int lprefixIndex, lSufixIndex;
            if (lPrefixProps.length() == 0) {
                lprefixIndex = 0;
            } else {
                lprefixIndex = lPrefixProps.length() - 1;
            }
            if (lSufixProps.length() == 0) {
                lSufixIndex = 0;
            } else {
                lSufixIndex = lSufixProps.length();
            }
            String lmethodName = "get" + fieldName.substring(lprefixIndex, fieldName.length() - lSufixIndex);
            Method method = forName.getMethod(lmethodName);
            lReturn = method.getReturnType().getName();
        } catch (Exception ex) {
        }
        return lReturn;
    }
}
